package com.smart.thrift.config.server;

import cn.hutool.core.util.ArrayUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;

import java.util.Collection;

public class ThriftServiceBeanScanProcessor implements ApplicationContextAware, BeanFactoryPostProcessor, EnvironmentAware,
        ResourceLoaderAware {

    private static final String DEFAULT_SCAN_PACKAGE = "";
    private ApplicationContext applicationContext;
    private Environment environment;
    private ResourceLoader resourceLoader;
    private final String[] packagesToScan;

    public ThriftServiceBeanScanProcessor(String[] packagesToScan) {
        this.packagesToScan = packagesToScan;
    }

    public ThriftServiceBeanScanProcessor(Collection<String> packagesToScan) {
        this(packagesToScan.toArray(new String[]{}));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinitionRegistry definitionRegistry = (BeanDefinitionRegistry) beanFactory;
        ThriftServiceBeanScanner beanScanner = new ThriftServiceBeanScanner(definitionRegistry, applicationContext, environment, resourceLoader);
        beanScanner.setBeanNameGenerator(new AnnotationBeanNameGenerator());
        beanScanner.setScopedProxyMode(ScopedProxyMode.INTERFACES);
        beanScanner.scan(ArrayUtil.isEmpty(packagesToScan) ? ArrayUtil.append(packagesToScan, DEFAULT_SCAN_PACKAGE) : packagesToScan);
    }
}
